package com.shopoo.oauth.app;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.shopoo.dto.PageResponse;
import com.shopoo.dto.Response;
import com.shopoo.dto.SingleResponse;
import com.shopoo.exception.BizException;
import com.shopoo.oauth.api.UserService;
import com.shopoo.oauth.app.converter.AppConverter;
import com.shopoo.oauth.domain.entity.Role;
import com.shopoo.oauth.domain.entity.User;
import com.shopoo.oauth.domain.repository.RoleRepository;
import com.shopoo.oauth.domain.repository.UserRepository;
import com.shopoo.oauth.domain.service.UserDomainService;
import com.shopoo.oauth.domain.valueobject.UserQuery;
import com.shopoo.oauth.dto.clientobject.RoleCO;
import com.shopoo.oauth.dto.clientobject.TokenCO;
import com.shopoo.oauth.dto.clientobject.UserCO;
import com.shopoo.oauth.dto.clientobject.UserDetailDTO;
import com.shopoo.oauth.dto.cqe.LoginCmd;
import com.shopoo.oauth.dto.cqe.UserAddCmd;
import com.shopoo.oauth.dto.cqe.UserPowerUpdateCmd;
import com.shopoo.oauth.dto.cqe.UserQry;
import com.shopoo.oauth.dto.cqe.UserUpdateCmd;
import com.shopoo.oauth.dto.cqe.UserUpdateStatusCmd;
import com.shopoo.oauth.infrastructure.client.OauthClient;
import com.shopoo.oauth.infrastructure.client.dto.TokenResponse;
import org.redisson.api.RedissonClient;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @Description 用户服务实现
 * @Date 2020/10/29 2:32 下午
 * @Author <a href="mailto:android_li@sina.cn">Joe</a>
 **/
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;

    @Resource
    private RoleRepository roleRepository;

    @Resource
    private UserDomainService userDomainService;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private OauthClient oauthClient;

    @Value("${security.oauth2.client.clientId}")
    private String clientId;

    @Value("${security.oauth2.client.clientSecret}")
    private String clientSecret;

    @Override
    public Response add(UserAddCmd userAddCmd) {
        User user = AppConverter.INSTANCE.toUser(userAddCmd);
        userRepository.add(user);
        return Response.buildSuccess();
    }

    @Override
    public Response updateUserStatus(UserUpdateStatusCmd userUpdateStatusCmd) {
        User user = AppConverter.INSTANCE.toUser(userUpdateStatusCmd);
        userRepository.updateById(user);
        return Response.buildSuccess();
    }

    @Override
    public SingleResponse<UserDetailDTO> findUserInfo(String userId) {
        return null;
    }

    @Override
    public PageResponse<UserCO> findByConditions(UserQry userQry) {
        UserQuery userQuery = AppConverter.INSTANCE.toUserQuery(userQry);
        PageResponse<User> pageResponse = userRepository.getPageByConditions(userQuery);
        List<UserCO> userCOS = Optional.of(pageResponse.getData()).get().stream().map(user1 -> {
            return AppConverter.INSTANCE.toUserCO(user1);
        }).collect(Collectors.toList());
        return PageResponse.of(userCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageNum());
    }

    @Override
    public Response updateById(UserUpdateCmd userUpdateCmd) {
        User user = AppConverter.INSTANCE.toUser(userUpdateCmd);
        userRepository.updateById(user);
        return Response.buildSuccess();
    }

    @Override
    public Response updatePower(UserPowerUpdateCmd userPowerUpdateCmd) {
        return null;
    }

    @Override
    public SingleResponse<TokenCO> login(LoginCmd loginCmd) {
        Map<String, String> parameters = new HashMap<>();
        parameters.put("client_id", clientId);
        parameters.put("client_secret", clientSecret);
        parameters.put("grant_type", "password");
        parameters.put("username", loginCmd.getUsername());
        parameters.put("password", loginCmd.getPassword());
        TokenResponse tokenResponse = oauthClient.getToken(parameters);
        return SingleResponse.of(AppConverter.INSTANCE.toTokenCO(tokenResponse));
    }

    @Override
    public SingleResponse<UserCO> findByUserId(String userId) {
        User user = userRepository.getByUserId(userId);
        if (user != null) {
            user.setPassword(null);
            List<Role> roles = roleRepository.findByUserId(userId);
            List<RoleCO> roleCOS = roles.stream().map(role -> {
                return AppConverter.INSTANCE.toRoleCO(role);
            }).collect(Collectors.toList());
            UserCO userCO = AppConverter.INSTANCE.toUserCO(user);
            userCO.setRoles(roleCOS);
            return SingleResponse.of(userCO);
        }
        return SingleResponse.of(null);
    }

    @Override
    public Response checkUsername(String username) {
        UserQuery userQuery = new UserQuery();
        userQuery.setUsername(username);
        List<User> list = userRepository.getByConditions(userQuery);
        if (list != null && !list.isEmpty()) {
            throw new BizException("用户名或电话号码已被使用!");
        }
        return Response.buildSuccess();
    }

}
